/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 2 -*- */
/**
* @file accelerometer.cpp
* 
* Library for managing the accelerometers.
* 
* @author Miguel Ángel Vílchez López 2010 <sacra@openmatica.es>
*
* Code derived from openmoko.org ( accelerometer data retrieval ).
* @sa http://wiki.openmoko.org/wiki/Accelerometer_data_retrieval
*
* Codigo is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* 
* Codigo is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License along
* with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "accelerometer.hpp"
#include "debug.cpp"

CMAccelerometer::CMAccelerometer(const char* file,bool debug=false,const char* filename=""):debug(debug,filename)
{
	this->file = (char*)malloc((strlen(file)+1)*sizeof(char));
	strcpy(this->file,file);
	this->x=this->y=this->z=0;
}

CMAccelerometer::~CMAccelerometer()
{
	free(this->file);
}

int CMAccelerometer::readAll(int fd, struct input_event* buf)
{
	int count = sizeof(struct input_event);
	int n_read = 0;
		while (n_read != count) {
				int result = read(fd, buf + n_read, count - n_read);
				if (result < 0)
						return result;
				else if (result == 0)
						return n_read;
				n_read += result;
		}
		return n_read;
}

void CMAccelerometer::check()
{
	int fd,ret;
	struct input_event ev;

	this->debug.debug("Trying to open the device...");
	if ((fd = open(this->file, O_RDONLY)) == -1)
	{
		this->debug.error(strerror(errno),__FILE__,__FUNCTION__,(__LINE__));
		exit(EXIT_FAILURE);
	}
	
	// Retrieve data
	while(ev.type != 3)
	{
		this->debug.debug("Trying to read the values of the device...");
		ret = this->readAll(fd,&ev);
		if (ret != sizeof(struct input_event))
		{
			this->debug.error(strerror(errno),__FILE__,__FUNCTION__,(__LINE__));
			exit(EXIT_FAILURE);
		}
		
		switch(ev.code)
		{
			case 0:
				this->x=ev.value;
				break;
			case 1:
				this->y=ev.value;
				break;
			case 2:
				this->z=ev.value;
				break;
		}
		
	}
	
	close(fd);
}

int CMAccelerometer::getValue(int dimension)
{
  switch(dimension)
  {
		case 0:
			return this->x;
			break;
		case 1:
			return this->y;
			break;
		case 2:
			return this->z;
			break;
	}  
  return -1;
}

int CMAccelerometer::getValue(char dimension)
{
  switch(dimension)
  {
		case 'x':
			return this->x;
			break;
		case 'y':
			return this->y;
			break;
		case 'z':
			return this->z;
			break;
	}  
  return -1;
}
